Move csv & style handlers to real C++ containers
authorRobert Lipe <robertlipe@gpsbabel.org>
Sun, 22 Jul 2018 05:19:50 +0000 (00:19 -0500)
committerRobert Lipe <robertlipe@gpsbabel.org>
Sun, 22 Jul 2018 05:19:50 +0000 (00:19 -0500)
Goal: eliminate lots of manual string bashing.

Currently waffles between the two approaches, but I wanted to get this
into GitHub for valgrind results.

csv_util.cc
csv_util.h
gui/setup.iss

index 6bfcc9349daf9d64b62c81f0493ff6b1fc118f5f..24b31290e2cafe54b00b20e372d5d8b3bd0bce7c 100644 (file)
@@ -183,8 +183,8 @@ csv_stringclean(const QString& source, const QString& to_nuke)
   return r.remove(QRegExp(regex));
 }
 
-// csv_stringtrim() - trim whitespace and leading and trailing 
-//                    enclosures (quotes) 
+// csv_stringtrim() - trim whitespace and leading and trailing
+//                    enclosures (quotes)
 //                    returns a copy of the modified string
 //    usage: p = csv_stringtrim(string, "\"", 0)
 char*
@@ -243,9 +243,9 @@ csv_stringtrim(const char* string, const char* enclosure, int strip_max)
   return (tmp);
 }
 
-// Is this really the replacement for the above?  
+// Is this really the replacement for the above?
 QString
-csv_stringtrim(const QString& source, const QString& enclosure) 
+csv_stringtrim(const QString& source, const QString& enclosure)
 {
   QString r = source;
   r.replace(enclosure, "");
@@ -754,16 +754,16 @@ XcsvFile::XcsvFile() {
   is_internal = false;
   ifield_ct = ofield_ct = 0;
   extension = description = nullptr;
-//   xcsv_file_init(); 
+//   xcsv_file_init();
 }
 
-void validate_fieldmap(field_map_t* fmp, bool is_output) {
+static void validate_fieldmap(const field_map_t* fmp, bool is_output) {
   QString qkey = fmp->key;
   QString qval = fmp->val;
   QString qprintfc = fmp->printfc;
 
   if (qkey.isEmpty()) {
-    Fatal() << MYNAME << ": xcsv style is missing" << 
+    Fatal() << MYNAME << ": xcsv style is missing" <<
             (is_output ? "output" : "input") << "field type.";
   }
   if (!fmp->val) {
@@ -779,7 +779,7 @@ void validate_fieldmap(field_map_t* fmp, bool is_output) {
 /* usage: xcsv_ifield_add("DESCRIPTION", "", "%s")                           */
 /*****************************************************************************/
 void
-xcsv_ifield_add(char* key, char* val, char* pfc)
+xcsv_ifield_add(const char* key, const char* val, const char* pfc)
 {
   field_map_t* fmp = (field_map_t*) xcalloc(sizeof(*fmp), 1);
   struct xt_mapping* xm = Perfect_Hash::in_word_set(key, strlen(key));
@@ -799,7 +799,7 @@ xcsv_ifield_add(char* key, char* val, char* pfc)
 /* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf")                      */
 /*****************************************************************************/
 void
-xcsv_ofield_add(char* key, char* val, char* pfc, int options)
+xcsv_ofield_add(const char* key, const char* val, const char* pfc, int options)
 {
   field_map_t* fmp = (field_map_t*) xcalloc(sizeof(*fmp), 1);
   struct xt_mapping* xm = Perfect_Hash::in_word_set(key, strlen(key));
@@ -928,7 +928,7 @@ writetime(const char* format, const gpsbabel::DateTime& t, bool gmt)
   return writetime(format, t.toTime_t(), gmt);
 }
 
-QString 
+QString
 writehms(const char* format, time_t t, int gmt)
 {
   static struct tm no_time = tm();
@@ -2197,6 +2197,39 @@ xcsv_noop(const route_head* wp)
   /* no-op */
 }
 
+// return |original| after performing token replacement.
+static QString
+xcsv_replace_tokens(const QString& original) {
+  QString replacement = original;
+    // Don't do potentially expensive replacements if token prefix
+    // isn't present;
+    if (original.contains("__")) {
+      struct tm tm;
+      time_t my_time = gpsbabel_time;
+      if (my_time == 0) {  /* testo script ? */
+        tm = *gmtime(&my_time);
+      } else {
+        tm = *localtime(&my_time);
+      }
+
+      replacement.replace("__FILE__", xcsv_file.fname);
+      replacement.replace("__VERSION__", my_time == 0 ? "" : gpsbabel_version);
+
+      QDateTime dt = QDateTime::fromTime_t(my_time);
+      dt = dt.toTimeSpec(Qt::UTC);
+
+      QString dts = dt.toString("ddd MMM dd hh:mm:ss yyyy");
+      replacement.replace("__DATE_AND_TIME__", dts);
+
+      QString d = dt.toString("MM/dd/yyyy");
+      replacement.replace("__DATE__", d);
+
+      QString t = dt.toString("hh:mm:ss");
+      replacement.replace("__TIME__", t);
+    }
+  return replacement;
+}
+
 /*****************************************************************************/
 /* xcsv_data_write(void) - write prologues, spawn the output loop, and write */
 /*                         epilogues.                                        */
@@ -2218,30 +2251,9 @@ xcsv_data_write(void)
   }
 
   /* output prologue lines, if any. */
-  foreach(const QString& line, xcsv_file.prologue) {
-    // If the XCSV description contains weird characters (like sportsim)
-    // this is where they get lost.
-   QString cout = line;
-
-    // Don't do potentially expensive replacements if token prefix 
-    // isn't present;
-    if (cout.contains("__")) {
-      cout.replace("__FILE__", xcsv_file.fname);
-      cout.replace("__VERSION__", time == 0 ? "" : gpsbabel_version);
-
-      QDateTime dt = QDateTime::fromTime_t(time);
-      dt = dt.toTimeSpec(Qt::UTC);
-
-      QString dts = dt.toString("ddd MMM dd hh:mm:ss yyyy");
-      cout.replace("__DATE_AND_TIME__", dts);
-
-      QString d = dt.toString("MM/dd/yyyy");
-      cout.replace("__DATE__", d);
-
-      QString t = dt.toString("hh:mm:ss");
-      cout.replace("__TIME__", t);
-    }
-    *xcsv_file.stream << cout <<  xcsv_file.record_delimiter;
+  for (auto line : xcsv_file.prologue) {
+   QString line_to_write = xcsv_replace_tokens(line);
+    *xcsv_file.stream << line_to_write <<  xcsv_file.record_delimiter;
   }
 
   if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) {
@@ -2255,8 +2267,9 @@ xcsv_data_write(void)
   }
 
   /* output epilogue lines, if any. */
-  foreach(const QString& ogp, xcsv_file.epilogue) {
-    *xcsv_file.stream << ogp << xcsv_file.record_delimiter;
+  for (auto line : xcsv_file.epilogue) {
+    QString line_to_write = xcsv_replace_tokens(line);
+    *xcsv_file.stream << line_to_write << xcsv_file.record_delimiter;
   }
 }
 #endif
index aeed5ce2ece120c746ac93027daec0fc26ec96ba..47de05d2d9b06136e8f26c610cf0316588b11b7e 100644 (file)
@@ -69,16 +69,16 @@ void
 xcsv_epilogue_add(char*);
 
 void
-xcsv_ifield_add(char*, char*, char*);
+xcsv_ifield_add(const char*, const char*, const char*);
 
 void
-xcsv_ofield_add(char*, char*, char*, int options);
+xcsv_ofield_add(const char*, const char*, const char*, int options);
 
 void
 xcsv_destroy_style(void);
 
 const char*
-xcsv_get_char_from_constant_table(char* key);
+xcsv_get_char_from_constant_table(const char* key);
 
 /****************************************************************************/
 /* types required for various xcsv functions                                */
@@ -90,9 +90,9 @@ xcsv_get_char_from_constant_table(char* key);
 #define OPTIONS_OPTIONAL 3
 typedef struct field_map {
   queue Q;
-  char* key;
-  char* val;
-  char* printfc;
+  const char* key;
+  const char* val;
+  const char* printfc;
   int hashed_key;
   int options;
 } field_map_t;
@@ -132,6 +132,8 @@ class XcsvFile {
 
   queue ifield;                /* input field mapping */
   queue* ofield;               /* output field mapping */
+  QList<field_map> ifields;
+  QList<field_map> ofields;
 
   int ifield_ct;               /* actual # of ifields */
   int ofield_ct;               /* actual # of ofields */
@@ -141,8 +143,8 @@ class XcsvFile {
   QTextCodec* codec;
   QString fname;                 /* ptr to filename of above. */
 
-  char* description;           /* Description for help text */
-  char* extension;             /* preferred filename extension (for wrappers)*/
+  const char* description;             /* Description for help text */
+  const char* extension;               /* preferred filename extension (for wrappers)*/
 
   short_handle mkshort_handle;/* handle for mkshort() */
   ff_type type;                /* format type for GUI wrappers. */
index 8ed735cd43598c5428d5f4191633088d10689966..4b8e163f5be40739885098a2c3b4463be4015e3c 100644 (file)
@@ -49,6 +49,7 @@ Source: "..\{#gui_build_dir_name}\release\*"; Excludes: "app.res,vcredist_*.exe,
 Source: "..\{#gui_build_dir_name}\release\vcredist_x86.exe"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist deleteafterinstall\r
 Source: "..\{#gui_build_dir_name}\release\vcredist_x64.exe"; DestDir: "{app}"; Flags: ignoreversion skipifsourcedoesntexist deleteafterinstall\r
 Source: "..\..\{#gpsbabel_build_dir_name}\release\gpsbabel.exe";       DestDir: "{app}"; Flags: ignoreversion\r
+; Source: release\help\*;              DestDir: "{app}\help"; Flags: ignoreversion recursesubdirs createallsubdirs\r
 \r
 ; Translation strings extracted from source code.  Include it in the dist\r
 ; so that users can translate if they want to.\r